package org.hhy.cloud.crawl.monitor.listener;

import cn.hutool.core.date.SystemClock;
import lombok.extern.slf4j.Slf4j;
import org.hhy.cloud.crawl.dto.CustomSpiderStatusEventDto;
import org.hhy.cloud.crawl.entity.Job;
import org.hhy.cloud.crawl.entity.JobMonitor;
import org.hhy.cloud.crawl.entity.enums.JobStatusEnums;
import org.hhy.cloud.crawl.monitor.CustomSpiderStatusMXBean;
import org.hhy.cloud.crawl.monitor.event.CustomSpiderEvent;
import org.hhy.cloud.crawl.service.JobMonitorService;
import org.hhy.cloud.crawl.service.JobService;
import org.hhy.cloud.crawl.vo.JobVO;
import org.lht.boot.cache.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import static org.hhy.cloud.crawl.constant.CrawlConstant.RedisKey.JOB_MONITOR_STATUS_KEY;

/**
 * Description: 爬虫监控监听器，
 *
 * @Author lht
 * @Date 2020/11/3 10:32 PM
 **/
@Slf4j
@Component
public class CustomSpiderListener implements ApplicationListener<CustomSpiderEvent> {

    @Autowired
    private JobMonitorService jobMonitorService;

    @Autowired
    private RedisUtil<String, JobMonitor> redisUtil;


    @Override
    public void onApplicationEvent(CustomSpiderEvent customSpiderEvent) {
        CustomSpiderStatusEventDto customSpiderStatusEventDto = customSpiderEvent.getSource();
        ConcurrentHashMap<String, CustomSpiderStatusMXBean> concurrentHashMap = customSpiderStatusEventDto.getConcurrentHashMap();
        JobMonitor job = customSpiderStatusEventDto.getJobMonitor();
        breakLabel:
        while (true) {

            for (Map.Entry<String, CustomSpiderStatusMXBean> entry : concurrentHashMap.entrySet()) {
                String id = customSpiderStatusEventDto.getId();
                CustomSpiderStatusMXBean v = entry.getValue();
                String name = v.getName();
                job.setTotalPageCount(v.getTotalPageCount());
                job.setThread(v.getThread());
                job.setSuccessPageCount(v.getSuccessPageCount());
                job.setErrorPageCount(v.getErrorPageCount());
                try {
                    job.setPagePerSecond(v.getPagePerSecond());
                } catch (ArithmeticException e) {
                    job.setPagePerSecond(0);
                }
                if ("Stopped".equals(v.getStatus()) || v.getTotalPageCount() == v.getSuccessPageCount()) {
                    job.setEndTime(SystemClock.now());
                    job.setStatus(JobStatusEnums.SUCCESS.getCode());
                    jobMonitorService.upsert(job);
                    redisUtil.delete(JOB_MONITOR_STATUS_KEY + name);
                    break breakLabel;
                }
                if ("Init".equals(v.getStatus())) {
                    job.setStatus(JobStatusEnums.WAIT.getCode());
                    redisUtil.set(JOB_MONITOR_STATUS_KEY + name, job, 60*60);
                }
                if ("Running".equals(v.getStatus())) {
                    job.setStatus(JobStatusEnums.RUNNING.getCode());
                    redisUtil.set(JOB_MONITOR_STATUS_KEY + name, job, 60*60);
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    log.error(e.getMessage());
                    break breakLabel;
                }
            }
        }
    }
}
